package cc.vv.party.service.impl

import cc.vv.party.beans.vo.*
import cc.vv.party.common.constants.StatusCode
import cc.vv.party.common.constants.SysConsts
import cc.vv.party.common.wrapper.PageWrapper
import cc.vv.party.exception.BizException
import cc.vv.party.mapper.LearningFieldMapper
import cc.vv.party.processor.http.RemoteService
import cc.vv.party.service.LearningFieldService
import cc.vv.party.service.OrgService
import cn.hutool.core.date.DatePattern
import cn.hutool.core.date.DateUtil
import com.baomidou.mybatisplus.plugins.Page
import commonx.core.content.isNotNullOrEmpty
import commonx.core.content.transfer
import commonx.core.date.*
import org.apache.commons.lang.StringUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.math.BigDecimal
import java.math.RoundingMode
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.LinkedHashMap

/**
 * 学习园地
 * @author: zhangx
 * @date 2018/11/12 16:56
 * @version 1.0.0
 * @description
 **/
@Service
open class LearningFieldServiceImpl : LearningFieldService {

    @Autowired
    lateinit var remoteService: RemoteService

    @Autowired
    lateinit var mapper: LearningFieldMapper

    @Autowired
    lateinit var orgService: OrgService

    override fun findFeelingPageList(branchType: String, branchId: String,
        page: Int,
        size: Int
    ): PageWrapper<FeelingVO> {
        var pages = Page<FeelingVO>(page, size)

        var branchIdList = ArrayList<String>()
        if (StringUtils.isNotBlank(branchId) && StringUtils.isNotBlank(branchType)) {
            val children = orgService.findPartyNode(branchType, branchId)
            findAllPartyBranchList(children, branchIdList)
            pages.records = mapper.findFeelingPageList(pages, branchIdList)
        }

        return pages.transfer()
    }

    override fun findPartyConstitutionPageList(page: Int, size: Int): PageWrapper<PartyConstitutionVO> {
        var pages = Page<PartyConstitutionVO>(page, size)
        pages.records = mapper.findPartyConstitutionPageList(pages)
        return pages.transfer()
    }

    override fun findSeriesSpeechPageList(page: Int, size: Int): PageWrapper<SeriesSpeechVO> {
        var pages = Page<SeriesSpeechVO>(page, size)
        pages.records = mapper.findSeriesSpeechPageList(pages)
        return pages.transfer()
    }

    override fun findSubjectList(): List<SubjectVO> {
        return mapper.findSubjectList()
    }

    override fun findOpenClassList(subjectId: String, page: Int, size: Int): PageWrapper<OpenClassVO> {
        var pages = Page<OpenClassVO>(page, size)
        pages.records = mapper.findOpenClassList(pages, subjectId)
        return pages.transfer()
    }

    override fun findExperiencePageList(branchType: String, branchId: String,
        page: Int,
        size: Int
    ): PageWrapper<ExperienceVO> {
        var pages = Page<ExperienceVO>(page, size)
        var branchIdList = ArrayList<String>()
        if (StringUtils.isNotBlank(branchId) && StringUtils.isNotBlank(branchType)) {
            val children = orgService.findPartyNode(branchType, branchId)
            findAllPartyBranchList(children, branchIdList)
            pages.records = mapper.findExperiencePageList(pages, branchIdList)
        }
        return pages.transfer()
    }

    override fun findOnlineExamPageList(page: Int, size: Int): PageWrapper<OnlineExamVO> {
        var pages = Page<OnlineExamVO>(page, size)
        pages.records = mapper.findOnlineExamPageList(pages)
        return pages.transfer()
    }

    override fun findQuestionPageList(blankId: String, page: Int, size: Int): PageWrapper<QuestionVO> {
        var pages = Page<QuestionVO>(page, size)
        pages.records = mapper.findQuestionPageList(pages, blankId)
        return pages.transfer()
    }

    override fun findEducationTypeList(): List<Map<String, String>> {
        return mapper.findEducationTypeList()
    }

    override fun findEducationPageList(typeId: String, page: Int, size: Int): PageWrapper<EducationVO> {
        var pages = Page<EducationVO>(page, size)
        pages.records = mapper.findEducationPageList(pages, typeId)
        return pages.transfer()
    }

    override fun getMessageInfo(type: Int, url: String): String {
        var content: String? = ""
        var urlType = when (type) {
            0 -> SysConsts.PARTY_CONSTITUTION_CONTENT_URL //党建党章
            1 -> SysConsts.SERIES_SPEECH_CONTENT_URL //讲话系列
            2 -> SysConsts.OPEN_CLASS_CONTENT_URL //微百科
            else -> throw BizException(StatusCode.MESSAGE_NOT_EXIST.statusCode, "类型信息未定义")
        }

        val call = remoteService.getThreeLessonContent("$urlType$url.txt")
        val response = call.execute()
        if (response.isSuccessful) {
            content = response.body()?.string()
        }
        return content ?: ""
    }


    override fun findPartyOrgMemberStatistics(id: String, type: String): Map<String, Int> {
        var list = when (type) {
            SysConsts.BranchType.REGION_LEVEL_DISTRICT ->  mapper.findPartyOrgMemberStatistics()
            SysConsts.BranchType.PARTY_COMMITTEE ->  mapper.findCompanyPartyOrgUserStatis(id)
            SysConsts.BranchType.PARTY_WORK_COMMITTEE ->  mapper.findPartyWorkCommitteeOrgUserStatis(id)
            SysConsts.BranchType.PARTY_TOTAL_BRANCH ->  mapper.findPartyTotalBranchOrgUserStatis(id)
            SysConsts.BranchType.PARTY_BRANCH ->  mapper.findPartyBranchPartyOrgUserStatis(id)
            else -> throw BizException(StatusCode.FIELD_VALUE_ERROR.statusCode, "TYPE类型值输入错误")
        }

        var result = HashMap<String, Int>()
        for (map in list) {
            result[map["type"].toString()] = map["num"]!!.toInt()
        }
        return result
    }

    /********  start 微感悟统计  *****************************************************************/

    override fun getFeelingStatistics(): FeelingStatisticsVO {
        var feelingStatisticsVO = FeelingStatisticsVO()
        feelingStatisticsVO.allCount = mapper.getAllCount()//统计微感悟总数
        feelingStatisticsVO.monthAdd = mapper.getMonthAdd() //本月新增
        feelingStatisticsVO.sumCount = mapper.getBySumCount() //审核通过总数
        feelingStatisticsVO.monthAddCount = mapper.getByMonthAddCount() //本月审核通过新增
        feelingStatisticsVO.workReleaseCount = mapper.getWorkReleaseCount() //本周发布总数
        feelingStatisticsVO.workAddCount = mapper.getByWorkAddCount() //本周审核通过新增
        feelingStatisticsVO.newFeelingList = mapper.findRealTimeStatistics() //实时统计
        return feelingStatisticsVO
    }

    override fun getFeelingStatisticsDataTrend(startTime: Long?, endTime: Long?): FeelingStatisticsDataTrendVO {
        var result = FeelingStatisticsDataTrendVO()

        var start = if (startTime == null) {
            DateUtil.format(DateUtil.beginOfMonth(Date()), DatePattern.NORM_DATETIME_FORMAT)
        } else {
            DateUtil.format(DateUtil.beginOfMonth(Date(startTime)), DatePattern.NORM_DATETIME_FORMAT)
        }

        var end = if (endTime == null) {
            DateUtil.format(DateUtil.endOfMonth(Date()), DatePattern.NORM_DATETIME_FORMAT)
        } else {
            DateUtil.format(DateUtil.endOfMonth(Date(endTime)), DatePattern.NORM_DATETIME_FORMAT)
        }


        var fabu = mapper.getFeelingDataTrend(start, end)
        if (fabu != null) {
            var zongshu = LinkedHashMap<String, Integer>()
            for (temp in fabu) {
                zongshu[temp["time"].toString()] = Integer(temp["count"].toString().toInt())
            }
            result.zongshu = zongshu
        }

        var tongguo = mapper.getFeelingByDataTrend(start, end)
        if (tongguo != null) {
            var tg = LinkedHashMap<String, Integer>()
            for (temp in tongguo) {
                tg[temp["time"].toString()] = Integer(temp["count"].toString().toInt())
            }
            result.tongguo = tg
        }

        return result
    }

    override fun getFeelingByDataDetail(
        time: String?,
        branchId: String?,
        sumDesc: Int,
        byDesc: Int,
        page: Int,
        size: Int
    ): PageWrapper<FeelingDataDetailVO> {
        var date = if (StringUtils.isEmpty(time)) {
            DateUtil.format(Date(), "yyyy-MM")
        } else {
            time
        }

        var pages = Page<FeelingDataDetailVO>(page, size)
        pages.records = mapper.getFeelingByDataDetail(pages, date!!, branchId, sumDesc, byDesc)
        return pages.transfer()
    }

    /********  end   微感悟统计  *****************************************************************/
    override fun getExperienceStatistics(): ExperienceStatisticsVO {
        return mapper.getExperienceStatistics()
    }

    override fun getExperienceStatisticsDataTrend(date: Long?): ExperienceStatisticsDataTrendVO {
        var result = ExperienceStatisticsDataTrendVO()

        var start: String
        var end: String
        if (date == null) {
            start = DateUtil.format(DateUtil.beginOfMonth(Date()), DatePattern.NORM_DATETIME_FORMAT)
            end = DateUtil.format(DateUtil.endOfMonth(Date()), DatePattern.NORM_DATETIME_FORMAT)
        } else {
            start = DateUtil.format(DateUtil.beginOfMonth(Date(date)), DatePattern.NORM_DATETIME_FORMAT)
            end = DateUtil.format(DateUtil.endOfMonth(Date(date)), DatePattern.NORM_DATETIME_FORMAT)
        }


        var fabu = mapper.getExperienceDataTrend(start, end)
        if (fabu != null) {
            var zongshu = LinkedHashMap<String, Integer>()
            for (temp in fabu) {
                zongshu[temp["time"].toString()] = Integer(temp["count"].toString().toInt())
            }
            result.zongshu = zongshu
        }

        val tongguo = mapper.getExperienceByDataTrend(start, end)
        if (tongguo != null) {
            var tg = LinkedHashMap<String, Integer>()
            for (temp in tongguo) {
                tg[temp["time"].toString()] = Integer(temp["count"].toString().toInt())
            }
            result.tongguo = tg
        }

        return result
    }

    override fun getExperienceByDataDetail(
        time: String?,
        branchId: String?,
        branchType: String?,
        page: Int,
        size: Int
    ): PageWrapper<ExperienceDataDetailVO> {
        var date = if (StringUtils.isEmpty(time)) {
            DateUtil.format(Date(), "yyyy-MM")
        } else {
            time
        }

        var pages = Page<ExperienceDataDetailVO>(page, size)
        pages.records = mapper.getExperienceByDataDetail(pages, date!!, branchId, branchType)
        return pages.transfer()
    }

    /********  end   心得体会统计  *****************************************************************/

    /********  start   在线考试统计  *****************************************************************/

    //在线考试统计头部方块数据
    override fun examTotalStatistics(): ExamTotalStatisticsVO {
        val result = ExamTotalStatisticsVO()

        val now = Date()
        //本周开始
        val weekStart = now.beginOfWeek().beginTimeOfDay().time.dateFormat()
        //本周结束
        val weekEnd = now.endOfWeek().endTimeOfDay().time.dateFormat()
        //本月开始
        val thisMonthStart = now.beginOfMonth().beginTimeOfDay().time.dateFormat()
        //本月结束
        val thisMonthEnd = now.endOfMonth().endTimeOfDay().time.dateFormat()
        //上月开始
        val lastMonthStart = now.lastMonth().beginOfMonth().beginTimeOfDay().time.dateFormat()
        //上月结束
        val lastMonthEnd = now.lastMonth().endOfMonth().endTimeOfDay().time.dateFormat()

        //本月月份
        val thisMonth = now.month()
        val lastMonth = now.lastMonth().month()

        //本周新增用户
        result.weekUserCnt = mapper.selectTotalUserStatistics(weekStart, weekEnd)
        //本周新增套题数量
        result.weekExamQuestionCnt = mapper.selectTotalExamStatistics(weekStart, weekEnd)
        //累计答题用户
        result.totalAnswerUserCnt = mapper.selectTotalUserStatistics(null, null)
        //周平均分
        result.averageScore = ((mapper.selectAverageScore(weekStart, weekEnd) ?: BigDecimal(0)).setScale(
            2,
            RoundingMode.HALF_UP
        ).toDouble() * 100).toString()

        //本月新增答题用户
        val thisMonthUserCnt = mapper.selectTotalUserStatistics(thisMonthStart, thisMonthEnd)
        val lastMonthUserCnt = mapper.selectTotalUserStatistics(lastMonthStart, lastMonthEnd)
        val incrementCnt = thisMonthUserCnt.toInt() - lastMonthUserCnt.toInt()
        result.monthIncrementUserCnt = if (incrementCnt > 0) incrementCnt.toString() else 0.toString()

        //累计答题数量
        val lastYearList = mapper.selectTotalAnswerQuestionStatisticsBefore("2017")
        var totalAnswerCnt = BigDecimal(0)
        var totalErrorCnt = BigDecimal(0)
        var totalRightCnt = BigDecimal(0)

        if (lastYearList != null && lastYearList.isNotEmpty())
            for (index in 1..12) {
                totalAnswerCnt += lastYearList["MONTH${index}ANSWERCOUNT"]!!
                totalErrorCnt += lastYearList["MONTH${index}ERRORCOUNT"]!!
                totalRightCnt += lastYearList["MONTH${index}SUCCESSCOUNT"]!!
            }

        var thisMonthRightAnswerCnt = totalRightCnt
        var lastMonthRightAnswerCnt = totalRightCnt
        val thisYearList = mapper.selectTotalAnswerQuestionStatistics("2017")

        if (thisYearList != null && thisYearList.isNotEmpty()) {
            for (index in 1..12) {
                totalAnswerCnt += thisYearList["MONTH${index}ANSWERCOUNT"]!!
                totalErrorCnt += thisYearList["MONTH${index}ERRORCOUNT"]!!
                totalRightCnt += thisYearList["MONTH${index}SUCCESSCOUNT"]!!
                if (index <= thisMonth) {
                    thisMonthRightAnswerCnt = totalRightCnt
                }
                if (index <= lastMonth) {
                    lastMonthRightAnswerCnt = totalRightCnt
                }
            }
        }

        result.totalAnswerQuestionCnt = totalAnswerCnt.toString()

        //本月新增套题数量
        result.monthExamQuestionCnt = mapper.selectTotalExamStatistics(thisMonthStart, thisMonthEnd)

        //平均合格率
        result.averageQualifiedRate =
                "${(BigDecimal(totalRightCnt.toDouble() / totalAnswerCnt.toDouble()).setScale(
                    2,
                    RoundingMode.HALF_UP
                ).toDouble() * 100).toInt()}%"

        //上升合格率
        result.monthQualifiedIncrementCnt =
                "${(BigDecimal((thisMonthRightAnswerCnt.toDouble() / totalAnswerCnt.toDouble()) - (lastMonthRightAnswerCnt.toDouble() / totalAnswerCnt.toDouble()))
                    .setScale(2, RoundingMode.HALF_UP).toDouble() * 100).toInt()}%"

        //累计平均分
        result.totalAverageScore = ((mapper.selectAverageScore(null, null) ?: BigDecimal(0)).setScale(
            2,
            RoundingMode.HALF_UP
        ).toDouble() * 100).toString()

        //平均分上升
        val thisMonthAvgScore = (mapper.selectAverageScore(thisMonthStart, thisMonthEnd) ?: BigDecimal(0)).setScale(
            2,
            RoundingMode.HALF_UP
        ).toDouble() * 100

        val lastMonthAvgScore = (mapper.selectAverageScore(lastMonthStart, lastMonthEnd) ?: BigDecimal(0)).setScale(
            2,
            RoundingMode.HALF_UP
        ).toDouble() * 100

        result.totalAverageScoreIncrementCnt =
                if (thisMonthAvgScore - lastMonthAvgScore > 0) (thisMonthAvgScore - lastMonthAvgScore).toString() else 0.toString()

        //优秀率
        result.averageExcellentRate =
                "${(BigDecimal(mapper.selectAvgScoreByMonth(null).toDouble() / result.totalAnswerUserCnt!!.toDouble()).setScale(
                    2,
                    RoundingMode.HALF_UP
                ).toDouble() * 100).toInt()}%"

        //优秀率上升
        val lastMonthAvgExcellent =
            mapper.selectAvgScoreByMonth(lastMonthEnd).toDouble() / result.totalAnswerUserCnt!!.toDouble()
        val thisMonthAvgExcellent =
            mapper.selectAvgScoreByMonth(thisMonthEnd).toDouble() / result.totalAnswerUserCnt!!.toDouble()
        result.monthExcellentIncrementCnt = "${(BigDecimal(thisMonthAvgExcellent - lastMonthAvgExcellent).setScale(
            2,
            RoundingMode.HALF_UP
        ).toDouble() * 100).toInt()}%"
        return result
    }

    // type 0:全部，1，优秀人数 2，合格人数 3，不合格人数 4，优秀率 5，合格率，6，不合格率
    override fun examTrendStatistics(type: Int, timeType: Int): List<ExamTrendVO> {
        val now = Date()
        var before = 7
        when (timeType) {
            0 -> before = 7
            1 -> before = 15
            2 -> before = 30
        }
        val start = now.before(Calendar.DAY_OF_MONTH, before).beginTimeOfDay().time.dateFormat()
        val end = now.endTimeOfDay().time.dateFormat()
        return when (type) {
            0 -> mapper.selectExamTrend(0, start, end)//全部
            1 -> mapper.selectExamTrend(1, start, end)//优秀人数
            2 -> mapper.selectExamTrend(2, start, end)//合格人数
            3 -> mapper.selectExamTrend(3, start, end)//不合格人数
            4 -> {//优秀率
                val totalList = mapper.selectExamTrend(0, start, end)
                val excellentMap = mapper.selectExamTrend(1, start, end).associateBy { it.dayTime }
                totalList.map {
                    val vo = ExamTrendVO()
                    vo.dayTime = it.dayTime
                    val excellentVo = excellentMap[it.dayTime]
                    if (excellentVo == null) {
                        vo.answerUserCnt = "0%"
                    } else {
                        vo.answerUserCnt =
                                "${(BigDecimal(excellentVo.answerUserCnt!!.toDouble() / it.answerUserCnt!!.toDouble()).setScale(
                                    2,
                                    RoundingMode.HALF_UP
                                ).toDouble() * 100).toInt()}%"
                    }
                    vo
                }.toList()
            }
            5 -> {//合格率
                val totalList = mapper.selectExamTrend(0, start, end)
                val qualifiedMap = mapper.selectExamTrend(2, start, end).associateBy { it.dayTime }
                totalList.map {
                    val vo = ExamTrendVO()
                    vo.dayTime = it.dayTime
                    val excellentVo = qualifiedMap[it.dayTime]
                    if (excellentVo == null) {
                        vo.answerUserCnt = "0%"
                    } else {
                        vo.answerUserCnt =
                                "${(BigDecimal(excellentVo.answerUserCnt!!.toDouble() / it.answerUserCnt!!.toDouble()).setScale(
                                    2,
                                    RoundingMode.HALF_UP
                                ).toDouble() * 100).toInt()}%"
                    }
                    vo
                }.toList()
            }
            6 -> {//不合格率
                val totalList = mapper.selectExamTrend(0, start, end)
                val unqualifiedList = mapper.selectExamTrend(3, start, end).associateBy { it.dayTime }
                totalList.map {
                    val vo = ExamTrendVO()
                    vo.dayTime = it.dayTime
                    val excellentVo = unqualifiedList[it.dayTime]
                    if (excellentVo == null) {
                        vo.answerUserCnt = "0%"
                    } else {
                        vo.answerUserCnt =
                                "${(BigDecimal(excellentVo.answerUserCnt!!.toDouble() / it.answerUserCnt!!.toDouble()).setScale(
                                    2,
                                    RoundingMode.HALF_UP
                                ).toDouble() * 100).toInt()}%"
                    }
                    vo
                }.toList()
            }
            else -> mapper.selectExamTrend(0, start, end)

        }
    }

    override fun findQuestionBlankList(): List<OnlineExamVO> {
        return mapper.findQuestionBlankList()
    }

    override fun findOnlineExamDataDetail(
        blankId: String,
        date: String?,
        branchId: String?,
        branchType: String?,
        sort: Int,
        page: Int,
        size: Int
    ): PageWrapper<OnlineStudyDataDetailVO> {
        var datetime = if (StringUtils.isNotBlank(date)) {
            date
        } else {
            DateUtil.format(Date(), "yyyy-MM")
        }

        var branchIdList = ArrayList<String>()
        if (StringUtils.isNotBlank(branchId) && StringUtils.isNotBlank(branchType)) {
            val children = orgService.findPartyNode(branchType, branchId)
            findAllPartyBranchList(children, branchIdList)
        }

        var pages = Page<OnlineStudyDataDetailVO>(page, size)
        pages.records = mapper.findOnlineExamDataDetail(pages, blankId, datetime!!, branchIdList, sort)
        return pages.transfer()
    }

    private fun findAllPartyBranchList(list: List<NodeVO>?, result: MutableList<String>) {
        if (list != null && list.isEmpty()) {
            return
        }
        for (node in list!!) {
            if (node.type == SysConsts.BranchType.PARTY_BRANCH) {
                if (node.id.isNotNullOrEmpty()) {
                    result.add(node.id!!)
                }
            } else {
                val nodeList = orgService.findPartyNode(node.type, node.id)
                findAllPartyBranchList(nodeList, result)
            }
        }
    }

    override fun findAreaTree(): AreauserVO {
        var result = AreauserVO()
        var list = mapper.findAreaTree()
        var child = ArrayList<AreauserVO>()
        for (temp in list) {
            if (temp.level!!.toInt() == 2) {
                result = temp
            } else {
                child.add(temp)
            }
        }
        result.child = child
        return result
    }

    override fun getStandardData(areaUserId: Int, year: Integer?, month: Integer?): StandardDataVO {
        var yearParam = year ?: DateUtil.year(Date())
        var monthParam = month ?: DateUtil.month(Date())
        return mapper.getStandardData(areaUserId, yearParam.toString().toInt(), monthParam.toString().toInt())
    }

    /********  end   在线考试统计  *****************************************************************/
}